<?php
//
//	file: includes/class_cash_points.php
//	begin: 07/12/2006
//	$Author: christopher $
//	$Revision: 14 $
//	$Date: 2007-10-08 14:55:03 +0000 (Mon, 08 Oct 2007) $
//	license: http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL)
//
//	description: classes for accessing cash data, including the cash table, user's cash, etc

if ( !defined('IN_PHPBB') )
{
	die('Hacking attempt');
	exit;
}

class cash_table extends cache
{
	var $currencies;
	var $ordered_list;
	var $id_list;
	function cash_table()
	{
		global $db;
		parent::cache('dta_cash_tbl', $config->data['cache_path'], $config->data['cache_disabled_cash_tbl']);
		$this->currencies = array();
		$this->ordered_list = array();
		$this->id_list = array();
		$this->refresh_table();
	}
	function read($force=false)
	{
		$this->refresh_table($force);
	}
	function refresh_table($force=false)
	{
		global $db;
		global $config;
		$this->currencies = array();
		$this->ordered_list = array();
		$this->id_list = array();
		$this->count_cache = array();
		
		$sql = "SELECT * FROM " . CASH_TABLE . " ORDER BY cash_order ASC";
		$this->data = $this->sql_query($sql, __LINE__, __FILE__, $force, 'cash_id');
		foreach($this->data as $row)
		{
			$cash_id = $row['cash_id'];
			$this->ordered_list[] = $cash_id;
			$this->id_list[$cash_id] = true;
			$this->currencies[$cash_id] = new cash_currency($row);
		}
	}
	function reorder()
	{
		global $db;
		$bad_ordering = false;
		$sql = array();
		for ( $i = 0; $i < count($this->ordered_list); $i++ )
		{
			if ( $this->currencies[$this->ordered_list[$i]]->data('cash_order') != ($i + 1) )
			{
				$sql[] = "UPDATE " . CASH_TABLE . " SET cash_order = " . ($i + 1) . " WHERE cash_id = " . $this->ordered_list[$i];
				$bad_ordering = true;
			}
		}
		if ( $bad_ordering )
		{
			for ( $i = 0; $i < count($sql); $i++ )
			{
				$db->sql_query($sql[$i], false, __LINE__, __FILE__, false);
			}
			$this->refresh_table(true);
		}
	}
	function currency_exists($cash_id)
	{
		if ( isset($this->id_list[$cash_id]) )
		{
			return true;
		}
		return false;
	}
	function &currency_next(&$iterater, $mask = false,$forum_id = false)
	{
		if ( empty($iterater) )
		{
			$iterater = 0;
		}
		if ( !($iterater < count($this->ordered_list)) )
		{
			$iterater = 0;
			return false;
		}
		$cash_id = $this->ordered_list[$iterater];

		if ( !$mask )
		{
			$iterater++;
			return $this->currencies[$cash_id];
		}

		while ( !$this->currencies[$cash_id]->mask($mask,$forum_id) )
		{
			$iterater++;
			if ( !($iterater < count($this->ordered_list)) )
			{
				$iterater = 0;
				return false;
			}
			$cash_id = $this->ordered_list[$iterater];
		}
		$iterater++;
		return $this->currencies[$cash_id];
	}
	function currency_count($mask = false,$forum_id = false)
	{
		if ( !$mask )
		{
			return count($this->ordered_list);
		}
		$count = 0;
		$i = 0;

		while ( $i < count($this->ordered_list) )
		{
			$cash_id = $this->ordered_list[$i];
			if ( $this->currencies[$cash_id]->mask($mask,$forum_id) )
			{
				$count++;
			}
			$i++;
		}
		return $count;
	}
	function currency($cash_id)
	{
		if ( !$this->currency_exists($cash_id) )
		{
			return false;
		}
		return $this->currencies[$cash_id];
	}
}

class cash_currency
{
	var $currency;
	var $forumlist;
	function cash_currency(&$data, $is_group = false)
	{
		$this->currency = $data;
		if ( !$is_group )
		{
			$this->forumlist = array();
			if ( strlen($data['cash_forumlist']) )
			{
				$templist = explode(',',$data['cash_forumlist']);
				for ( $i = 0; $i < count($templist); $i++ )
				{
					$this->forumlist[$templist[$i]] = 1;
				}
			}
		}
	}
	function data($identifier)
	{
		return $this->currency[$identifier];
	}
	function id()
	{
		return $this->currency['cash_id'];
	}
	function name($surpress_image = false,$quotes = false)
	{
		global $phpbb_root_path;
		if ( $this->mask(CURRENCY_IMAGE) && !$surpress_image )
		{
			return '<img src="' . $phpbb_root_path . $this->currency['cash_imageurl'] . '" alt="' . quoteslash($this->currency['cash_name'],'"') . '" />';
		}
		else
		{
			return (( !$quotes ) ? $this->currency['cash_name'] : quoteslash($this->currency['cash_name'],$quotes));
		}
	}
	function db()
	{
		return $this->currency['cash_dbfield'];
	}
	function display($amount,$surpress_image = false,$quotes = false)
	{
		if( $this->mask(CURRENCY_PREFIX) )
		{
			return ($this->name($surpress_image,$quotes,$bbcode) . ' ' . $amount);
		}
		else
		{
			return ($amount . ' ' . $this->name($surpress_image,$quotes));
		}
	}
	function mask($bitmask = false,$forum_id = false)
	{
		if ( !$bitmask )
		{
			return true;
		}
		if ( (($bitmask & $this->currency['cash_settings']) == $bitmask) && (!$forum_id || $this->forum_active($forum_id)) )
		{
			return true;
		}
		return false;
	}
	function exchange()
	{
		return $this->currency['cash_exchange']/$this->factor();
	}
	function base($newthread = false)
	{
		return (( $newthread ) ? $this->perpost() : $this->perreply());
	}
	function perpost()
	{
		return $this->currency['cash_perpost']/$this->factor();
	}
	function postbonus()
	{
		return $this->currency['cash_postbonus']/$this->factor();
	}
	function perreply()
	{
		return $this->currency['cash_perreply']/$this->factor();
	}
	function perchar()
	{
		return $this->currency['cash_perchar']/$this->factor(PERCHAR_DEC_BONUS);
	}
	function maxearn()
	{
		return $this->currency['cash_maxearn']/$this->factor();
	}
	function perpm()
	{
		return $this->currency['cash_perpm']/$this->factor();
	}
	function allowanceamount()
	{
		return $this->currency['cash_allowanceamount']/$this->factor();
	}
	function factor($modifier = false)
	{
		$exp = 0;
		if ( !$modifier )
		{
			$exp = intval($this->currency['cash_decimals']);
		}
		else
		{
			$exp = intval($this->currency['cash_decimals']) + $modifier;
		}
		return intval(pow(10,intval(max(0,$exp))));
	}
	function attribute_pack($key,$value)
	{
		$keys = array('cash_exchange'=>1,'cash_perpost'=>1,'cash_postbonus'=>1,'cash_perreply'=>1,'cash_perchar'=>1,'cash_maxearn'=>1,'cash_perpm'=>1,'cash_allowanceamount'=>1);
		if ( isset($keys[$key]) )
		{
			if ( $key == 'cash_perchar' )
			{
				return intval($value * $this->factor(PERCHAR_DEC_BONUS));
			}
			else
			{
				return intval($value * $this->factor());
			}
		}
		else return $value;
	}
	function forum_active($forum_id)
	{
		return ( ( isset($this->forumlist[$forum_id]) ) ? ( !$this->mask(CURRENCY_FORUMLISTTYPE) ) : ( $this->mask(CURRENCY_FORUMLISTTYPE) ) );
	}
}

class cash_groups
{
	var $groups;
	var $groups_ordered_list;
	var $loaded;
	var $ranks;
	function cash_groups()
	{
		$this->loaded = false;
		$this->groups = array(CASH_GROUPS_LEVEL => array(),CASH_GROUPS_RANK => array(),CASH_GROUPS_USERGROUP => array());
		$this->groups_ordered_list = array(CASH_GROUPS_LEVEL => array(),CASH_GROUPS_RANK => array(),CASH_GROUPS_USERGROUP => array());
		$this->ranks = array();
	}
	function load($force_reload = false,$all_entries = false)
	{
		global $db, $cash;
		if ( !$force_reload && $this->loaded )
		{
			return;
		}
		$currencies_array = array();
		$mask = false;
		if ( !$all_entries )
		{
			while ( $c_cur = &$cash->currency_next($cm_i,CURRENCY_ENABLED) )
			{
				$currencies_array[] = $c_cur->id();
			}
		}
		if ( count($currencies_array) || $all_entries )
		{
			if ( !$all_entries )
			{
				$sql = "SELECT *
						FROM " . CASH_GROUPS_TABLE . "
						WHERE cash_id = " . implode(' OR cash_id = ',$currencies_array);
			}
			else
			{
				$sql = "SELECT *
						FROM " . CASH_GROUPS_TABLE;
			}
			$result = $db->sql_query($sql, false, __LINE__, __FILE__, false);
			while ( $row = $db->sql_fetchrow($result) )
			{
				$type = $row['group_type'];
				$group = $row['group_id'];
				if ( !isset($this->groups[$type][$group]) )
				{
					$this->groups[$type][$group] = array();
					$this->groups_ordered_list[$type][] = $group;
				}
				$this->groups[$type][$group][] = new cash_group($row);
			}
		}
		$sql = "SELECT *
				FROM " . RANKS_TABLE . "
				WHERE rank_special = 0
				ORDER BY rank_min ASC";
		$result = $db->sql_query($sql, false, __LINE__, __FILE__, false);
		while ( $row = $db->sql_fetchrow($result) )
		{
			$this->ranks[] = $row;
		}
		$this->loaded = true;
	}
	function get_groups(&$returnarray,$level,$usergroups,$postcount)
	{
		if ( isset($this->groups[CASH_GROUPS_LEVEL][$level]) )
		{
			for ( $j = 0; $j < count($this->groups[CASH_GROUPS_LEVEL][$level]); $j++ )
			{
				$returnarray[$this->groups[CASH_GROUPS_LEVEL][$level][$j]->id()][] = &$this->groups[CASH_GROUPS_LEVEL][$level][$j];
			}
		}
		for ( $i = 0; $i < count($this->ranks); $i++ )
		{
			if ( isset($this->groups[CASH_GROUPS_RANK][$this->ranks[$i]['rank_id']]) && ($this->ranks[$i]['rank_min'] <= $postcount ) )
			{
				for ( $j = 0; $j < count($this->groups[CASH_GROUPS_RANK][$this->ranks[$i]['rank_id']]); $j++ )
				{
					$returnarray[$this->groups[CASH_GROUPS_RANK][$this->ranks[$i]['rank_id']][$j]->id()][] = &$this->groups[CASH_GROUPS_RANK][$this->ranks[$i]['rank_id']][$j];
				}
			}
		}
		for ( $i = 0; $i < count($usergroups); $i++ )
		{
			if ( isset($this->groups[CASH_GROUPS_USERGROUP][$usergroups[$i]]) )
			{
				for ( $j = 0; $j < count($this->groups[CASH_GROUPS_USERGROUP][$usergroups[$i]]); $j++ )
				{
					$returnarray[$this->groups[CASH_GROUPS_USERGROUP][$usergroups[$i]][$j]->id()][] = &$this->groups[CASH_GROUPS_USERGROUP][$usergroups[$i]][$j];
				}
			}
		}
	}
	function populate(&$returnarray,$type,$id)
	{
		if ( isset($this->groups[$type]) && is_array($this->groups[$type]) && isset($this->groups[$type][$id]) && is_array($this->groups[$type][$id]) )
		{
			for ( $i = 0; $i < count($this->groups[$type][$id]); $i++ )
			{
				$returnarray[$this->groups[$type][$id][$i]->id()] = &$this->groups[$type][$id][$i];
				$this->groups[$type][$id][$i]->load();
			}
		}
	}
	function cleanup()
	{
		global $db;
		$clause_1 = array();
		$types = array(CASH_GROUPS_LEVEL,CASH_GROUPS_RANK,CASH_GROUPS_USERGROUP);
		for ( $pre_i = 0; $pre_i < count($types); $pre_i++ )
		{
			$clause_2 = array();
			$i = $types[$pre_i];
			for ( $pre_j = 0; $pre_j < count($this->groups_ordered_list[$i]); $pre_j++ )
			{
				$clause_3 = array();
				$j = $this->groups_ordered_list[$i][$pre_j];
				for ( $pre_k = 0; $pre_k < count($this->groups[$i][$j]); $pre_k++ )
				{
					if( !$this->groups[$i][$j][$pre_k]->is_loaded() )
					{
						$k = $this->groups[$i][$j][$pre_k]->id();
						$clause_3[] = 'cash_id = ' . $k;
					}
				}
				if ( count($clause_3) )
				{
					if ( count($clause_3) == count($this->groups[$i][$j]) )
					{
						$clause_2[] = 'group_id = ' . $j;
					}
					else if ( count($clause_3) == 1 )
					{
						$clause_2[] = 'group_id = ' . $j . ' AND ' . $clause_3[0];
					}
					else
					{
						$clause_2[] = 'group_id = ' . $j . ' AND (' . implode(' OR ',$clause_3) . ')';
					}
				}
			}
			if ( count($clause_2) )
			{
				if ( count($clause_2) == 1 )
				{
					$clause_1[] = 'group_type = ' . $i . ' AND ' . $clause_2[0];
				}
				else
				{
					$clause_1[] = 'group_type = ' . $i . ' AND ((' . implode(') OR (',$clause_2) . '))';
				}
			}
		}
		if ( count($clause_1) )
		{
			$whereclause = '';
			if ( count($clause_1) == 1 )
			{
				$whereclause = $clause_1[0];
			}
			else
			{
				$whereclause = '(' . implode(') OR (',$clause_1) . ')';
			}
			$sql = "DELETE FROM " . CASH_GROUPS_TABLE . "
					WHERE " . $whereclause;
			$db->sql_query($sql, false, __LINE__, __FILE__, false);
		}
	}
}

class cash_forumgroup
{
	var $group_type;
	var $group_id;
	var $group_name;
	var $group_description;
	var $currency_settings;
	function cash_forumgroup($group_type,$group_id,$group_name,$group_description)
	{
		$this->group_type = $group_type;
		$this->group_id = $group_id;
		$this->group_name = $group_name;
		$this->group_description = $group_description;
		$this->currency_settings = array();
	}
	function load()
	{
		global $cm_groups;
		$cm_groups->populate($this->currency_settings,$this->group_type,$this->group_id);
	}
	function has_entries()
	{
		return (count($this->currency_settings) > 0 );
	}
}

class cash_group extends cash_currency
{
	var $group_type;
	var $group_id;
	var $cash_id;
	var $loaded;
	function cash_group($rows)
	{
		$this->cash_currency($rows,true);
		$this->group_type = $rows['group_type'];
		$this->group_id = $rows['group_id'];
		$this->cash_id = $rows['cash_id'];
	}
	function name($surpress_image = false,$quotes = false)
	{
		global $cash;
		return $cash->currencies[$this->cash_id]->name($surpress_image,$quotes);
	}
	function factor($modifier = false)
	{
		global $cash;
		return $cash->currencies[$this->cash_id]->factor($modifier);
	}
	function is_loaded()
	{
		return $this->loaded;
	}
	function load()
	{
		$this->loaded = true;
	}
}

class cash_user
{
	var $user_id;
	var $userdata;
	var $userdata_stored;
	var $usergroups;
	var $cashgroups;
	var $cashgroups_init;
	function cash_user($user_id,$userdata = false)
	{
		$this->user_id = $user_id;
		$data_user = new user;
		$data_user->read($user_id);
		$this->userdata = $data_user->data;
		$this->userdata_stored = true;

		$this->usergroups = array();
		$this->cashgroups = array();
		$this->cashgroups_init = false;
	}
	function get_userdata()
	{
		if ( !$this->userdata_stored )
		{
			$data_user = new user;
			$data_user->read($this->user_id);
			$this->userdata = $data_user->data;
			$this->userdata_stored = true;
		}
	}
	function id()
	{
		return $this->user_id;
	}
	function name()
	{
		$this->get_userdata();
		return $this->userdata['username'];
	}
	function get_cashgroups()
	{
		global $db, $cm_groups, $cash;
		$this->get_userdata();
		if ( !$this->cashgroups_init )
		{
			$cm_groups->load();
			$this->usergroups = explode(',', $this->userdata['group_user_list']);
			while ( $c_cur = &$cash->currency_next($cm_i) )
			{
				$this->cashgroups[$c_cur->id()] = array();
				$this->cashgroups[$c_cur->id()][] = &$cash->currencies[$c_cur->id()];
			}
			$cm_groups->get_groups($this->cashgroups,$this->userdata['user_level'],$this->usergroups,$this->userdata['user_posts']);
			$this->cashgroups_init = true;
		}
	}
	function get_setting($cash_id,$attribute,$modifier = false)
	{
		global $cash;
		if ( !$cash->currency_exists($cash_id) )
		{
			return false;
		}
		$this->get_cashgroups();
		$sum = 0;
		for ( $i = 0; $i < count($this->cashgroups[$cash_id]); $i++ )
		{
			$sum += intval($this->cashgroups[$cash_id][$i]->data($attribute));
		}
		$sum /= $cash->currencies[$cash_id]->factor($modifier);
		return $sum;
	}
	function give_bonus($forum_id)
	{
		global $db, $cash;
		if ( $this->user_id == ANONYMOUS )
		{
			return;
		}
		$this->get_cashgroups();
		$clause = array();
		while ( $c_cur = &$cash->currency_next($cm_i,CURRENCY_ENABLED,$forum_id) )
		{
			$sum = $this->get_setting($c_cur->id(),'cash_postbonus');
			if ( $sum != 0 )
			{
				$clause[] = $c_cur->db() . ' = ' . $c_cur->db() . ' + ' . $sum;
				$this->userdata[$c_cur->db()] += $sum;
			}
		}
		if ( count($clause) )
		{
			$sql = "UPDATE " . USERS_TABLE . "
					SET " . implode(',',$clause) . "
					WHERE user_id = " . $this->user_id;
			$db->sql_query($sql, false, __LINE__, __FILE__, false);
		}
	}
	function give_pm_amount()
	{
		global $db, $cash;
		if ( $this->user_id == ANONYMOUS )
		{
			return;
		}
		$this->get_cashgroups();
		$clause = array();
		while ( $c_cur = &$cash->currency_next($cm_i,CURRENCY_ENABLED) )
		{
			$sum = $this->get_setting($c_cur->id(),'cash_perpm');
			if ( $sum != 0 )
			{
				$clause[] = $c_cur->db() . ' = ' . $c_cur->db() . ' + ' . $sum;
				$this->userdata[$c_cur->db()] += $sum;
			}
		}
		if ( count($clause) )
		{
			$sql = "UPDATE " . USERS_TABLE . "
					SET " . implode(',',$clause) . "
					WHERE user_id = " . $this->user_id;
			$db->sql_query($sql, false, __LINE__, __FILE__, false);
		}
	}
	function has($cash_id,$amount)
	{
		global $cash;
		$this->get_userdata();
		return ($this->userdata[$cash->currencies[$cash_id]->db()] >= $amount);
	}
	function amount($cash_id)
	{
		global $cash;
		$this->get_userdata();
		return $this->userdata[$cash->currencies[$cash_id]->db()];
	}
	function give_by_id_array($id_array)
	{
		global $db, $cash;
		if ( $this->user_id == ANONYMOUS )
		{
			return;
		}
		$sql_update = array();
		while ( $c_cur = &$cash->currency_next($cm_i) )
		{
			if ( isset($id_array[$c_cur->id()]) )
			{
				$sql_update[] = $c_cur->db() . ' = ' . $c_cur->db() . ' + ' . $id_array[$c_cur->id()];
				if ( $this->userdata_stored )
				{
					$this->userdata[$c_cur->db()] += $id_array[$c_cur->id()];
				}
			}
		}
		if ( count($sql_update) )
		{
			$sql = "UPDATE " . USERS_TABLE . "
					SET " . implode(', ',$sql_update) . "
					WHERE user_id = " . $this->user_id;
			$db->sql_query($sql, false, __LINE__, __FILE__, false);
		}
	}
	function remove_by_id_array($id_array)
	{
		global $db, $cash;
		if ( $this->user_id == ANONYMOUS )
		{
			return;
		}
		$sql_update = array();
		while ( $c_cur = &$cash->currency_next($cm_i) )
		{
			if ( isset($id_array[$c_cur->id()]) )
			{
				$sql_update[] = $c_cur->db() . ' = ' . $c_cur->db() . ' - ' . $id_array[$c_cur->id()];
				if ( $this->userdata_stored )
				{
					$this->userdata[$c_cur->db()] -= $id_array[$c_cur->id()];
				}
			}
		}
		if ( count($sql_update) )
		{
			$sql = "UPDATE " . USERS_TABLE . "
					SET " . implode(', ',$sql_update) . "
					WHERE user_id = " . $this->user_id;
			$db->sql_query($sql, false, __LINE__, __FILE__, false);
		}
	}
	function set_by_id_array($id_array)
	{
		global $db, $cash;
		if ( $this->user_id == ANONYMOUS )
		{
			return;
		}
		$sql_update = array();
		while ( $c_cur = &$cash->currency_next($cm_i) )
		{
			if ( isset($id_array[$c_cur->id()]) )
			{
				$sql_update[] = $c_cur->db() . ' = ' . $id_array[$c_cur->id()];
				if ( $this->userdata_stored )
				{
					$this->userdata[$c_cur->db()] = $id_array[$c_cur->id()];
				}
			}
		}
		if ( count($sql_update) )
		{
			$sql = "UPDATE " . USERS_TABLE . "
					SET " . implode(', ',$sql_update) . "
					WHERE user_id = " . $this->user_id;
			$db->sql_query($sql, false, __LINE__, __FILE__, false);
		}
	}
}

class cash_exchange extends cache
{
	function cash_exchange()
	{
		parent::cache('dta_exchange', $config->data['cache_path'], $config->data['cache_disabled_exchange']);
	}
	function read($force=false)
	{
		$ex_sql = "SELECT * FROM " . CASH_EXCHANGE_TABLE;
		$this->data = $this->sql_query($ex_sql, __LINE__, __FILE__, true);
	}
}

$cash = new cash_table();
$cm_groups = new cash_groups();


?>